package com.example.mq.service.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mq.enums.MsgStatusEnum;
import com.example.mq.mapper.MsgDelayMapper;
import com.example.mq.po.MsgDelayPO;
import com.example.mq.service.MsgDelayService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/*
@description:
@ClassName MsgDelayServiceImpl
@author chen
@create 2025-08-14 18:23
@Version 1.0
*/
@Service
public class MsgDelayServiceImpl extends ServiceImpl<MsgDelayMapper, MsgDelayPO> implements MsgDelayService
{

    @Override
    public List<MsgDelayPO> batchInsert(LocalDateTime expectSendTime, List<String> msgBodyJsonList)
    {
        //批量插入消息到db中
        List<MsgDelayPO> msgPOList = new ArrayList<>(msgBodyJsonList.size());
        for (String bodyJson : msgBodyJsonList)
        {
            MsgDelayPO msgDelayPO =  new MsgDelayPO();
            msgDelayPO.setId(IdUtil.fastSimpleUUID());
            msgDelayPO.setBodyJson(bodyJson);
            msgDelayPO.setStatus(MsgStatusEnum.INIT.getStatus());
            msgDelayPO.setExpectSendTime(expectSendTime);
            msgDelayPO.setFailMsg(null);
            msgDelayPO.setFailCount(0);
            msgDelayPO.setSendRetry(0);
            msgDelayPO.setCreateTime(LocalDateTime.now());
            msgPOList.add(msgDelayPO);
        }
        this.saveBatch(msgPOList);
        return msgPOList;
    }

    @Override
    public void updateStatusSuccess(MsgDelayPO msgDelayPO)
    {
        LocalDateTime now = LocalDateTime.now();
        LambdaUpdateWrapper<MsgDelayPO> updateWrapper = Wrappers.lambdaUpdate(MsgDelayPO.class)
                .eq(MsgDelayPO::getId, msgDelayPO.getId())
                .set(MsgDelayPO::getStatus, MsgStatusEnum.SUCCESS.getStatus())
                .set(MsgDelayPO::getSendRetry, 0)
                .set(MsgDelayPO::getActualSendTime, now)
                .set(MsgDelayPO::getUpdateTime, now);
        this.update(updateWrapper);
    }

    @Override
    public void updateStatusFail(MsgDelayPO msgDelayPO, String failMsg, boolean sendRetry, LocalDateTime nextRetryTime)
    {
        LocalDateTime now = LocalDateTime.now();
        LambdaUpdateWrapper<MsgDelayPO> updateWrapper = Wrappers.lambdaUpdate(MsgDelayPO.class)
                .eq(MsgDelayPO::getId, msgDelayPO.getId())
                .ne(MsgDelayPO::getStatus, MsgStatusEnum.SUCCESS.getStatus())
                .set(MsgDelayPO::getStatus, MsgStatusEnum.FAIL.getStatus())
                .set(MsgDelayPO::getFailMsg, failMsg)
                .set(MsgDelayPO::getSendRetry, sendRetry ? 1 : 0)
                .set(MsgDelayPO::getNextRetryTime, nextRetryTime)
                .setSql("fail_count = fail_count + 1")
                .set(MsgDelayPO::getActualSendTime, now)
                .set(MsgDelayPO::getUpdateTime, now);
        this.update(updateWrapper);
    }
}
